package com.yu.gulimall.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yu.common.constant.ProductConstant;
import com.yu.common.dto.SkusReduceInfoDto;
import com.yu.common.dto.SpuBoundsDto;
import com.yu.common.es.SkuEsModel;
import com.yu.common.utils.PageUtils;
import com.yu.common.utils.Query;
import com.yu.common.utils.R;
import com.yu.common.vo.SkuHasStockVo;
import com.yu.gulimall.product.dao.SpuInfoDao;
import com.yu.gulimall.product.entity.*;
import com.yu.gulimall.product.feign.CouponFeignService;
import com.yu.gulimall.product.feign.SearchFeignService;
import com.yu.gulimall.product.feign.WareFeignService;
import com.yu.gulimall.product.service.*;
import com.yu.gulimall.product.vo.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Resource
    private SpuInfoDescService spuInfoDescService;


    @Resource
    private SpuImagesService spuImagesService;

    @Resource
    private ProductAttrValueService productAttrValueService;


    @Resource
    private SkuInfoService skuInfoService;

    @Resource
    private SkuImagesService skuImagesService;


    @Resource
    private SkuSaleAttrValueService skuSaleAttrValueService;

    @Resource
    private CouponFeignService couponFeignService;

    @Resource
    private BrandService brandService;

    @Resource
    private CategoryService categoryService;

    @Resource
    private AttrService attrService;

    @Resource
    private WareFeignService wareFeignService;

    @Resource
    private SearchFeignService searchFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }


    @Transactional
    @Override
    public void saveSpu(SpuSaveVO spuInfo) {
        //1. 保存spu基本信息  表：pms_spu_info
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtil.copyProperties(spuInfo, spuInfoEntity);
        this.baseMapper.insert(spuInfoEntity);
        //2. 保存Spu的描述图片 表：pms_spu_info_desc
        List<String> decript = spuInfo.getDecript();
        String desc = StrUtil.join(",", decript);
        SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
        spuInfoDescEntity.setDecript(desc);
        Long spuId = spuInfoEntity.getId();
        spuInfoDescEntity.setSpuId(spuId);
        spuInfoDescService.save(spuInfoDescEntity);
        //3, 保存spu的图片集 表：pms_spu_images
        List<String> images = spuInfo.getImages();
        spuImagesService.saveImage(images, spuId);
        //4. 保存spu的规格参数 表：pms——product_attr_value
        List<BaseAttrs> baseAttrs = spuInfo.getBaseAttrs();
        productAttrValueService.saveProductValue(spuId, baseAttrs);


        //5. 保存spu的积分信息：huliamll_sms-sms_spu_bopunds
        SpuBoundsDto spuBoundsDto = new SpuBoundsDto();
        Bounds bounds = spuInfo.getBounds();
        BeanUtil.copyProperties(bounds, spuBoundsDto);
        spuBoundsDto.setSpuId(spuId);
        couponFeignService.saveBopondTo(spuBoundsDto);

        //6. 保存当前spu对应的所有sku信息
        List<Skus> skus = spuInfo.getSkus();
        skus.forEach(item -> {
            String defaultImage = "";
            List<Images> imagesList = item.getImages();
            for (Images img : imagesList) {
                if (img.getDefaultImg() == 1) {
                    defaultImage = img.getImgUrl();
                }
            }
            SkuInfoEntity skuInfo = new SkuInfoEntity();
            BeanUtil.copyProperties(item, skuInfo);
            skuInfo.setBrandId(spuInfoEntity.getBrandId());
            skuInfo.setCatalogId(spuInfoEntity.getCatalogId());
            skuInfo.setSkuDefaultImg(defaultImage);
            skuInfo.setSaleCount(0L);
            skuInfo.setSpuId(spuInfoEntity.getId());
            //6.1  sku的基本信息： pms_sku_info
            skuInfoService.save(skuInfo);
            Long skuId = skuInfo.getSkuId();
            List<SkuImagesEntity> skuImagesEntityList = imagesList.stream().map((img -> {
                SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                skuImagesEntity.setSkuId(skuId);
                skuImagesEntity.setImgUrl(img.getImgUrl());
                skuImagesEntity.setDefaultImg(img.getDefaultImg());
                return skuImagesEntity;
            })).collect(Collectors.toList());
            //6.2  sku的图片信息：pms_sku_images
            skuImagesService.saveBatch(skuImagesEntityList);
            //6.3  保存spu的规格参数：pms_product_attr_value
            List<Attr> attr = item.getAttr();
            List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = attr.stream().map(a -> {
                SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                BeanUtil.copyProperties(a, skuSaleAttrValueEntity);
                skuSaleAttrValueEntity.setSkuId(skuId);
                return skuSaleAttrValueEntity;
            }).collect(Collectors.toList());
            skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);
            //6.4  sku的优惠，满减等信息：

            SkusReduceInfoDto skusReduceInfoDto = new SkusReduceInfoDto();
            BeanUtil.copyProperties(item, skusReduceInfoDto);
            skusReduceInfoDto.setSkuId(skuId);
            couponFeignService.saveRecuceSkuInfo(skusReduceInfoDto);

        });
    }

    @Override
    public PageUtils getInfoList(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> infoEntityQueryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if (StrUtil.isNotBlank(key)) {
            infoEntityQueryWrapper.and(item -> {
                item.eq("spu_id", key).or().like("sku_name", key);
            });
        }
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                infoEntityQueryWrapper
        );
        return new PageUtils(page);
    }

    @Override
    public void up(Long spuId) {
        List<SkuInfoEntity> skuInfoEntities = skuInfoService.getSkuBySpuId(spuId);
        List<Long> skuIds = skuInfoEntities.stream().map(item -> item.getSkuId()).
                collect(Collectors.toList());
        // 查询当前sku所有的规格信息
        List<ProductAttrValueEntity> attrValueEntityList = productAttrValueService.list(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
        List<Long> allAttrIds = attrValueEntityList.stream().map(item -> {
            return item.getAttrId();
        }).collect(Collectors.toList());
        // 检索可用的id
        List<Long> attrIds=attrService.seletAttrIds(allAttrIds);
        Set<Long> attrSet=new HashSet<>(attrIds);
        List<SkuEsModel.Attrs> attrsList = attrValueEntityList.stream().filter(item -> {
            return attrSet.contains(item.getAttrId());
        }).map(item -> {
            SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
            BeanUtil.copyProperties(item, attrs);
            return attrs;
        }).collect(Collectors.toList());

        // 1）—— TODO: 2024/3/15 远程调用库存管理  查看是否存在库存
        Map<Long, Boolean> collect = null;
        try {

            R<List<SkuHasStockVo>> hasStock = wareFeignService.getHasStock(skuIds);
            List<SkuHasStockVo> tData = hasStock.getTData();
            collect = tData.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasStock));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


        // 设置es信息
        Map<Long, Boolean> finalCollect = collect;
        List<SkuEsModel> skuEsModels = skuInfoEntities.stream().map(item -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            BeanUtil.copyProperties(item, skuEsModel);


            if(finalCollect ==null){
                skuEsModel.setHasStock(false);
            }else {
                skuEsModel.setHasStock(finalCollect.get(skuEsModel.getSkuId()));
            }


            // 2）—— TODO: 2024/3/15 设置热度评分
            skuEsModel.setHotScore(0L);

            // 品牌信息
            BrandEntity brand = brandService.getById(skuEsModel.getBrandId());
            skuEsModel.setBrandName(brand.getName());
            skuEsModel.setBrandImg(brand.getLogo());
            // 分类信息
            CategoryEntity category = categoryService.getById(skuEsModel.getCatalogId());
            skuEsModel.setCatalogName(category.getName());
            // 规格参数
            skuEsModel.setAttrs(attrsList);

            return skuEsModel;
        }).collect(Collectors.toList());

        //TODO 返回给es
        R r = searchFeignService.productEsUp(skuEsModels);
        if(r.getCode()==0){
            // 远程调用成功 修改sku表中上架状态
            baseMapper.upStatus(spuId, ProductConstant.ProductStatusEnum.SPU_UP);
        } else {
            // 远程调用失败，记录日志
            // TODO: 2024/3/18 接口幂等性（重复调用问题）
        }

    }

}